package org.bongo.open.cumulo.procengine.runner;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.bongo.open.cumulo.core.context.CumuloContext;
import org.bongo.open.cumulo.core.message.MessageUnit;
import org.bongo.open.cumulo.procengine.broker.exceptions.ProcRunnerException;

public class SimpleJvmContainer implements ProcRunnerContainer {

	private OutputStream outStream;
	private InputStream inStream;
	private Process proc;
	private int identifier; 
	private Thread childProcReaderThread;
	
	private static class InputStreamDrainer implements Runnable{
		private InputStream inStream;
		private byte[] buffer = new byte[512];
		
		public InputStreamDrainer(InputStream inStream) {
			setInStream(inStream);
		}

		public void run() {
			try {
				drainChildProcInStream();
			} catch (ProcRunnerException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
			
		}

		private void drainChildProcInStream() throws ProcRunnerException {
			try {
				int readSize =0;
				while((readSize = inStream.read(buffer)) >= 0) {
					System.out.print(new String(buffer,0,readSize));
				}
			} catch (IOException e) {
				e.printStackTrace();
				throw new ProcRunnerException(e);
			}
		}
		
		public void setInStream(InputStream inStream) {
			this.inStream = inStream;
		}
		
	}
	
	
	public void startup(CumuloContext context) throws ProcRunnerException {
		System.out.println("starting proc");
		StringBuilder builder = new StringBuilder();
		builder.append("java -cp ");
		builder.append(System.getProperty("java.class.path"));
		builder.append(" ");
		builder.append(getClass().getCanonicalName());
		
		String[] cmdList = builder.toString().split(" ");
		ProcessBuilder procBuilder = new ProcessBuilder(cmdList);
		try {
			proc = procBuilder.start();

			outStream = proc.getOutputStream();
			inStream = proc.getInputStream();
			
			InputStreamDrainer childProcReader = new InputStreamDrainer(inStream);
			childProcReaderThread = new Thread(childProcReader);
			childProcReaderThread.start();
			
		} catch (IOException e) {
			e.printStackTrace();
			throw new ProcRunnerException(e);
		}
		
	}

	public void run(MessageUnit<?> message) throws ProcRunnerException {
		try {
			
			outStream.write( ("\n{instance id:}"+identifier+":: ").getBytes());
			outStream.write(message.getMessageContent().toString().getBytes());
			
		} catch (IOException e) {
			e.printStackTrace();
			throw new ProcRunnerException(e);
		}
	}

	
	public void cleanup(CumuloContext context) throws ProcRunnerException {
		try {
			outStream.close();
			childProcReaderThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
			throw new ProcRunnerException(e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new ProcRunnerException(e);
		}
	}
	
	public static void main(String[] args) throws IOException, InterruptedException {
		byte[] buffer = new byte[512];
		int readSize;
		
		while((readSize = System.in.read(buffer)) >= 0) {
			System.out.print(new String(buffer, 0, readSize));
		}
	}

	public void setIdentifier(int id) {
		identifier = id;
		
	}

}
